#ifndef __DEF_WXOSQLITE_H__
#define __DEF_WXOSQLITE_H__

#include <wx/wx.h>
#include "sqlite3.h"

#define WXSQL_ERROR 1000

#define WXSQL_INTEGER  1
#define WXSQL_FLOAT    2
#define WXSQL_TEXT     3
#define WXSQL_BLOB     4
#define WXSQL_NULL     5

typedef enum {
	SQL_default_tran = 0,
	SQL_deferred_tran,
	SQL_immediate_tran,
	SQL_exclusive_tran
} SQLTransactionType;

//-----------------------------------------------------------
//  wxSQLException class
//-----------------------------------------------------------
class wxSQLException
{
public:
	wxSQLException(int err, const wxString &msg);
	wxSQLException(const wxSQLException &e);
	virtual ~wxSQLException(void);

	int GetErrorCode(void) const
	{
		return errcode & 0xff;
	}
	int GetExtendedErrorCode(void) const
	{
		return errcode;
	}
	const wxString GetErrMessage(void) const
	{
		return errmsg;
	}
	static const wxString ErrorCodeAsString(int code);
private:
	int errcode;
	wxString errmsg;
};
//-----------------------------------------------------------
//  wxSQLResultSet class
//-----------------------------------------------------------
class wxSQLResultSet
{
public:
	wxSQLResultSet(void);
	wxSQLResultSet(const wxSQLResultSet &set);
	wxSQLResultSet(sqlite3 *db, sqlite3_stmt *stmt, bool eof, bool first = true, bool ownstmt = true);
	wxSQLResultSet &operator=(const wxSQLResultSet &result);
	virtual ~wxSQLResultSet(void);

	int GetColumnCount(void);
	wxString GetColumnName(int cols);
	wxString GetDeclaredColumnType(int cols);
	int GetColumnType(int cols);
	wxString GetDatabaseName(int cols);
	wxString GetTableName(int cols);
	int FindColumnIndex(const wxString &name);
	
	int GetInt(int cols, int nullValue = 0);
	//int GetInt(const wxString &colname, int nullValue = 0);
	wxLongLong GetInt64(int cols, wxLongLong nullValue = 0);
	//int GetInt64(const wxString &colname, wxLongLong nullValue = 0);
	double GetDouble(int cols, double nullValue = 0.0);
	//int GetDouble(const wxString &colname, double nullValue = 0.0);
	wxString GetString(int cols, const wxString &nullValue = wxEmptyString);
	//int GetString(const wxString &colname, const wxString &nullValue = wxEmptyString);
	wxDateTime GetDate(int cols);
	//wxDateTime GetDate(const wxString &colname);
	wxDateTime GetTime(int cols);
	//wxDateTime GetTime(const wxString &colname);
	wxDateTime GetDateTime(int cols);
	//wxDateTime GetDateTime(const wxString &colname);
	bool GetBool(int cols);
	//bool GetBool(const wxString &colname);
	bool IsNull(int cols);
	//bool IsNull(const wxString &colname);
	bool Eof(void);
	bool NextRow(void);
	void Finalize(void);
	wxString GetSQL(void);
private:
	bool CheckStmt(void);
	sqlite3 *maindb;
	sqlite3_stmt *mainstmt;
	bool iseof;
	bool isfirst;
	int colcount;
	bool isownstmt;
};
/*class wxSQLTable
{
public:
	wxSQLTable(void);
	wxSQLTable(const wxSQLTable &table);
	wxSQLTable(char **result, int rows, int cols);
	wxSQLTable &operator=(const wxSQLTable &table);
	virtual ~wxSQLTable(void);

	int GetColumnCount(void);
	int GetRowCount(void);
	wxString GetColumnName(int cols);
	
	int GetInt(int cols, int nullValue = 0);
	wxLongLong GetInt64(int cols, wxLongLong nullValue = 0);
	int GetDouble(int cols, double nullValue = 0.0);
	wxString GetString(int cols, const wxString &nullValue = wxEmptyString);
	wxDateTime GetDate(int cols);
	wxDateTime GetTime(int cols);
	wxDateTime GetDateTime(int cols);
	bool GetBool(int cols);
	bool IsNull(int cols);
	void SetRow(int row);
	void Finalize(void);
private:
	char **sql_results;
	bool sql_cols;
	bool sql_rows;
	int currentRow;
};*/


class wxSQLDatabase
{
public:
	wxSQLDatabase(void);
	virtual ~wxSQLDatabase(void);

	void Open(const wxString &filename);
	bool IsOpen(void);
	void Close(void);
	void Begin(SQLTransactionType tran = SQL_default_tran);
	void Commit(void);
	void Rollback(void);
	bool GetAutoCommit(void);
	bool TableExists(const wxString &table);
	bool CheckSyntax(const wxString &sql);
	int ExecuteUpdate(const wxString &sql);
	int ExecuteUpdate(const char *sql);
	wxSQLResultSet ExecuteQuery(const wxString &sql);
	wxSQLResultSet ExecuteQuery(const char *sql);
	int ExecuteScalar(const wxString &sql);
	int ExecuteScalar(const char *sql);
	//wxSQLTable GetTable(const wxString &sql);
	void Interrupt(void);
	void SetBusyTimeout(int ms);
	//void SetCommitHook(wxSQLHook *hook);
	//void SetRollbackHook(wxSQLHook *hook);
	//void SetUpdateHook(wxSQLHook *hook);

private:
	wxSQLDatabase& operator=(const wxSQLDatabase& db);
	void CheckDatabase(void);
	sqlite3 *maindb;
	int timeoutMs;
};

#endif